/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#ifndef __LOGGER_HDR__
#define __LOGGER_HDR__


#ifdef WIN32
	// disable - decorated name length exceeded
	#pragma warning(disable:4503)
	// disable 'identifier' truncation warning
	#pragma warning(disable:4786)
#endif

#include <sstream>
#include <stdexcept>
#include <vector>
#include <qfile.h>

namespace logging {

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	/*!
	 * \struct logger_error
	 */
	struct logger_error : public std::runtime_error {
		logger_error( const std::string& msg ) : std::runtime_error(msg) {}
	};

	/*!
	 *
	 */
	enum Level { DATA, INFO, WARN, ERRO, FATAL };
	
	/*!
	 *
	 */
	typedef std::pair< std::string, std::string > KeyValue;
	typedef std::vector< KeyValue > KVPairs;
	typedef KVPairs::const_iterator KVPairsCIt;


	/*!
	 * \class Logger logger.h
	 */
	class Logger {
	public:
		static void set_name( const std::string & );
		static Logger* instance();
		static void destroy();
	private:
		Logger();
		Logger( const std::string & );
		~Logger();
	public:
		void open_record( Level );
		void add_keyvalue( const std::string &, const std::string & );
		void add_keyvalue( const std::string &, const double &      );
		void close_record();

		void data( const char *, double );

		void info( const char * )const;
		void warning( const char * )const;
		void error( const char * )const;
		void fatal( const char * )const;

		void info( const KVPairs& )const;
		void warning( const KVPairs& )const;
		void error( const KVPairs& )const;
		void fatal( const KVPairs& )const;
	private:
		void init();
		std::string compose( const KVPairs& )const;
		void write( const char *, const char * )const;
		void write( const char * )const;
		const char * level2string( Level );
	private:
		static Logger* _instance;
		mutable QFile _file;

		Level              _level;
		std::string        _ostring;
		std::ostringstream _osstream;
	};

	
}; 

#endif 
